package com.cy.wangly.springcore.custom;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.type.classreading.MetadataReader;
import org.springframework.core.type.classreading.MetadataReaderFactory;
import org.springframework.core.type.filter.TypeFilter;
import org.springframework.util.MultiValueMap;

import java.io.IOException;
import java.lang.annotation.Annotation;
import java.util.Set;

public class WanglyIncludeChooserFilter implements TypeFilter {
    Logger logger = LoggerFactory.getLogger(WanglyIncludeChooserFilter.class);
    private String[] includedChooser;

    public WanglyIncludeChooserFilter() {
        init();
    }

    public void init() {
        includedChooser = null;
        StackTraceElement stack[] = Thread.currentThread().getStackTrace();
        String mainClassName = stack[stack.length - 1].getClassName();
        Class clazz = null;
        try {
            clazz = Class.forName(mainClassName);
        } catch (ClassNotFoundException e) {
            logger.error("main class is not found. className:" + mainClassName);
        }
        Annotation[] annotations = clazz.getAnnotations();
        for (Annotation annotation : annotations) {
            if (annotation.annotationType().equals(WanglyScan.class)) {
                WanglyScan ws = (WanglyScan) annotation;
                includedChooser = ws.includedChooser();
            }
        }
    }

    public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory)
            throws IOException {
        if (includedChooser == null || includedChooser.length == 0) {
            return false;
        }
        if (isNotChooser(metadataReader)) {
            return false;
        }
        if (isIncludedChooser(metadataReader)) {
            return false;
        }
        return true;
    }

    private boolean isIncludedChooser(MetadataReader metadataReader) {
        MultiValueMap<String, Object> valueMap = metadataReader.getAnnotationMetadata().getAllAnnotationAttributes(getClassName());
        String value = String.valueOf(valueMap.get("value").get(0));
        for (String s : includedChooser) {
            if (s.equals(value)) {
                return true;
            }
        }
        return false;
    }

    private boolean isNotChooser(MetadataReader metadataReader) {
        Set<String> annotations = metadataReader.getAnnotationMetadata().getAnnotationTypes();
        return !annotations.contains(getClassName());
    }

    private String getClassName() {
        return WanglyChooser.class.getName();
    }
}